package com.sora.sora.common.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import com.sora.sora.common.mapper.ArticleMapper;
import com.sora.sora.common.model.bo.ArticleBasicConvert;
import com.sora.sora.common.model.entity.ArticleEntity;
import com.sora.sora.common.model.param.ArticleParam;
import com.sora.sora.common.model.vo.ArticleVO;
import com.sora.sora.common.service.ArticleService;
import lombok.extern.log4j.Log4j2;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.Duration;
import java.util.List;

@Log4j2
@Service("articleService")
public class ArticleServiceImpl implements ArticleService {

    @Resource
    ArticleMapper articleMapper;

    @Resource
    RedisTemplate<String, String> redisStringTemplate;

    @Resource
    RedisTemplate<String, Object> redisObjectTemplate;

    @Resource
    ObjectMapper objectMapper;


    @Override
    public int count(int page, int limit) {
        PageHelper.startPage(page, limit);
        int count = articleMapper.count();
        return count;
    }

    @Override
    public int post(ArticleParam articleParam) {
        ArticleEntity articleEntity = new ArticleEntity(articleParam);
        if (articleMapper.add(articleEntity) > 0) {
            int id = articleEntity.getId();
            String param = null;
            try {
                param = objectMapper.writeValueAsString(articleParam);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
                log.error("文章序列化出错" + id + articleParam.getAuthor() + articleParam.getTitle());
            }
//            redisStringTemplate.opsForValue().setIfAbsent("pageObject:" + id, param, );
            redisStringTemplate.opsForValue().setIfAbsent("pageObject:" + id, param, Duration.ofDays(7));
            redisObjectTemplate.opsForHash().put("pageData","view:" + id, 0);
            redisObjectTemplate.opsForHash().put("pageData","like:" + id, 0);
            redisObjectTemplate.opsForHash().put("pageData","collection:" + id, 0);
            redisObjectTemplate.opsForList().leftPush("pageSync",id);
            return 1;
        }
        return 0;
    }

    @Override
    public int update(int id, String content) {
        if (redisStringTemplate.hasKey("pageObject:" + id)) {
            redisStringTemplate.delete("pageObject:" + id);
        }
        return articleMapper.update(id, content);
    }

    @Override
    public int delte(int id) {
        if (redisStringTemplate.hasKey("pageObject:" + id)) {
            redisStringTemplate.delete("pageObject:" + id);
            redisObjectTemplate.opsForHash().delete("pageData","view:" + id);
            redisObjectTemplate.opsForHash().delete("pageData", "like:" + id);
            redisObjectTemplate.opsForHash().delete("pageData", "collection:" + id);
        }
        return articleMapper.delete(id);
    }

    @Override
    public ArticleVO getById(int id) {
        ArticleEntity articleEntity = null;
        String result = redisStringTemplate.opsForValue().get("pageObject:" + id);
        int view;
        // redis有记录的话直接从redis拿
        if (result != null) {
            // 将字符串转化，字符串应为"id,author,title,content,uploadTime"
            try {
                articleEntity = objectMapper.readValue(result, ArticleEntity.class);
            } catch (JsonProcessingException e) {
                log.error("文章反序列化出错" + id );
                e.printStackTrace();
            }
            view = (int) redisObjectTemplate.opsForHash().get("pageData", "view:" + id);
            Integer like = (Integer) redisObjectTemplate.opsForHash().get("pageData","like:" + id);
            Integer collection = (Integer) redisObjectTemplate.opsForHash().get("pageData","collection:" + id);
            articleEntity.setView(view);
            articleEntity.setLike(like);
            articleEntity.setCollection(collection);
            redisObjectTemplate.opsForHash().increment("pageData","view:" + id,1);
        } else {
            if (articleMapper.queryById(id) != null) {
                articleEntity = articleMapper.queryById(id);
                // redis和mysql中都没有记录
            } else {
                return null;
            }
        }
        return ArticleBasicConvert.INSTANCE.entityToVO(articleEntity);
    }


    @Override
    public Long like(int id) {
        return redisObjectTemplate.opsForHash().increment("pageData", "like:" + id, 1);
    }
}
